// ==================================================================================
// Shared Genomics Project MPI Codebase
// Version 1.0 30/04/2010
//
// (c) 2010 University of Manchester all rights reserved
//
// This file is distributed under the GNU General Public License, Version 2.  
// Please see the file COPYING.txt for more details
// ==================================================================================

#ifndef _ADJUSTED_H_
#define _ADJUSTED_H_

#include "options.h"
#include "types.h"

#ifdef __cplusplus
extern "C" {
#endif

/*!
\file
\ingroup	gio
\brief		P-value Adjustment for multiple testing. 
\details	
	Algorithm based on the PLINK adjustment code for 1-D CHISQ calculations 
	but uses the simpler 'C' data-structures.
*/

/*! 
\brief Structure containing the %adjusted pvalue statistics.
\details 
	Each adjusted structure references a single SNP/Person p-value of a non-permuted calculation upon 
	an entire genomic data-set.
*/
struct adjusted {
	/*! \brief Benjamini & Hochberg (1995) step-up FDR control */
	double fdr_bh;

	/*! \brief Bonferroni single-step adjusted p-value */
	double bonf;

	/*! \brief Holm (1979) step-down adjusted p-values */
	double holm;

	/*! \brief CHISQ value of a non-permuted calculation */
	double chisq;

	/*! \brief T-distribution counter for quantitative traits (QT) */
	int tcnt;
};

/*! 
\brief Create an adjusted array
\details All numeric elements of \ref adjusted are initialised at zero.
\param [in] n Size of Array to create
\returns \ref adjusted array or NULL on failure.
*/
struct adjusted* adjusted_create_array(int n);

/*!
\brief Calculate adjusted pvalues.
\details 
	Make sure that the CHISQ scores are bound to the appropriate \ref adjusted::chisq
	before doing the calculation.<br>

\param [in, out] a The array of adjusted pvalues.
\param [in] nA Size of the array of adjusted pvalues.
\param [in] ops Parameter values for the adjustment calculation
*/
int adjusted_calc(struct adjusted *a, int nA, struct selected_options *ops);

/*! 
\brief Write an array of adjusted pvalues to file.
\details
	The output filename is bound to \ref selected_options::szAdjustedFileName
	and usually has the file suffix \ref SUFFIX_PADJ_FILE .
\param [in, out] a The array of adjusted pvalues.
\param [in] nA Size of the array of adjusted pvalues.
\param [in] ops Output file location
\return 1 on success or 0 on failure.
*/
int adjusted_write(struct adjusted *a, int nA, struct selected_options *ops);

/*! 
\brief Loads an adjusted pvalue array from file.
\details
	The input filename is bound to \ref selected_options::szAdjustedFileName
	and usually has the file suffix \ref SUFFIX_PADJ_FILE .
\param [in] ops Input file location
\param [in] size Pointer containg the size of the returned array
\return Array of \ref adjusted or NULL on failure.
*/
struct adjusted* adjusted_load(struct selected_options *ops, int *size);

/*!
\brief Write an 'adjusted' array to file and copy output to a remote directory.
\details
	The final output filename is a concatonation
	of \ref selected_options::rdir, selected_options::szRunId and \ref SUFFIX_PADJ_FILE.<br>
	The inital output file is written locally to the directory \ref selected_options::ldir.
\param [in, out] a The array of adjusted pvalues.
\param [in] nA Size of the array of adjusted pvalues.
\param [in] ops Output file location
\param [in] rank Processor local MPI rank
\return 1 on success or 0 on failure.
*/
int adjusted_write_and_copy(struct adjusted *a, int nA, struct selected_options *ops, int rank);

/*! \brief Loads an adjusted pvalue array from file.
\details
	Similar to \ref adjusted_load() but the input filename is a concatonation
	of \ref selected_options::rdir, \ref selected_options::szRunId and \ref SUFFIX_PADJ_FILE.<br>
	These tokens are bound to \ref selected_options::szAdjustedFileName and \ref adjusted_load() 
	called to load the adjusted p-value array from file.
\param [in] ops Input file location
\param [in] size Pointer containg the size of the returned array
\return Array of \ref adjusted or NULL on failure.
*/
struct adjusted* _adjusted_load(struct selected_options *ops, int *size);

#ifdef __cplusplus
}
#endif

#endif // _ADJUSTED_H_
